package com.tengju.bff.interfaces.manage.club.facade;

import com.tengju.bff.interfaces.manage.club.assembler.ClubAssembler;
import com.tengju.bff.interfaces.manage.club.vo.ClubInfoVO;
import com.tengju.bff.interfaces.manage.club.vo.ClubVO;
import com.tengju.bff.interfaces.manage.club.vo.PageClubInfoVO;
import com.tengju.bff.interfaces.manage.club.vo.UserWithClubVO;
import com.tengju.bff.interfaces.shared.PageAssembler;
import com.tengju.user.application.club.dto.ClubQueryDTO;
import com.tengju.user.domain.model.club.*;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.shared.BasePage;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author chenhang
 * @Date 2021/1/13
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ClubFacade {

    private final ClubRepository clubMetaRepository;
    private final ClubMemberRepository clubMemberRepository;
    private final UserInfoRepository userInfoRepository;
    private final ClubZoneRelationRepository clubZoneRelationRepository;
    private final ZoneRepository zoneRepository;

    public PageClubInfoVO listClubInfo(ClubQueryDTO clubQueryDTO) {
        PageClubInfoVO pageClubInfoVO = new PageClubInfoVO();
        PageAssembler.convert(clubQueryDTO);
        BasePage<Club> clubMetaPage = clubMetaRepository.query(
                clubQueryDTO.getClubId(),
                clubQueryDTO.getClubName(),
                clubQueryDTO.getFounderIdCode(),
                clubQueryDTO.getOffset(),
                clubQueryDTO.getPageSize()
                );
        pageClubInfoVO.setTotal(clubMetaPage.getTotal());
        pageClubInfoVO.setPageIndex(clubQueryDTO.getPageIndex());
        List<Club> clubs = clubMetaPage.getDatas();
        if (CollectionUtils.isEmpty(clubs)) {
            return pageClubInfoVO;
        }
        List<UserIdCode> founderIdCodes = clubs.stream()
                .map(Club::getFounderIdCode)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<ClubId> clubIds = clubs.stream().map(Club::getClubId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoRepository.batchGetUserInfo(founderIdCodes);
        Map<UserIdCode, UserInfo> userInfoMap = userInfos.stream()
                .collect(Collectors.toMap(k -> k.getIdCode(), v -> v, (v1, v2) -> v1));
        List<ClubZoneRelation> relations = clubZoneRelationRepository.batchGetByClubIds(clubIds);
        Map<ClubId, ZoneId> clubIdZoneIdMap = relations.stream()
                .collect(Collectors.toMap(k -> k.getClubId(), v -> v.getZoneId(), (v1, v2) -> v1));
        Map<ClubId,List<Long>> clubMemberMap = clubMemberRepository.batchGetMembers(clubIds);
        List<ClubInfoVO> clubInfoVOList = new ArrayList<>();
        for (Club club : clubs) {
            ClubInfoVO clubInfoVO = new ClubInfoVO();
            UserIdCode founderIdCode = club.getFounderIdCode();
            if (founderIdCode != null) {
                UserInfo founderUserInfo = userInfoMap.get(founderIdCode);
                if (founderUserInfo != null) {
                    clubInfoVO.setFounderIdCode(founderUserInfo.getIdCode().getValue());
                    clubInfoVO.setFounderNickName(founderUserInfo.getNickName());
                }
            }
            List<Long> members = clubMemberMap.get(club.getClubId());
            ZoneId zoneId = clubIdZoneIdMap.get(club.getClubId());
            if (zoneId != null) {
                clubInfoVO.setZoneId(zoneId.getValue());
                Zone zone = zoneRepository.findById(zoneId.getValue());
                if (zone != null) {
                    clubInfoVO.setZoneName(zone.getName());
                }
            }
            clubInfoVO.setClubId(club.getClubId().getValue());
            clubInfoVO.setClubName(club.getClubName());
            clubInfoVO.setClubHeadImg(club.getClubHeadImg());
            clubInfoVO.setMemberIdCodes(members);
            clubInfoVO.setOptTime(club.getUpdateTime());
            clubInfoVO.setOptUserName(club.getUpdateBy());
            clubInfoVOList.add(clubInfoVO);
        }
        pageClubInfoVO.setClubInfoVOList(clubInfoVOList);
        return pageClubInfoVO;
    }

    public UserWithClubVO getClubUserInfo(Long idCode) {
        ClubId clubId = clubMemberRepository.findClubIdByIdCode(UserIdCode.of(idCode));
        Club club = clubMetaRepository.findById(clubId);
        UserInfo userInfo = userInfoRepository.getByIdCode(UserIdCode.of(idCode));
        return ClubAssembler.convertToUserWithClub(club,userInfo);
    }

    public List<ClubVO> getAllClub() {
        List<Club> clubs = clubMetaRepository.queryAll();
        return clubs.stream().map(ClubAssembler::convertToClubListVo).collect(Collectors.toList());
    }
}
